﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using Microsoft.Xna.Framework;

namespace CoreLib
{
    public partial class PropertiesUserControl : UserControl
    {
        struct ControlValueStructure
        {
           public object TargetObject;
           public object TargetInfo;
           public object ParentObject;
           public object ParentInfo;
        }
        private object SelectedObject = new object();
       private ControlValueStructure controlvalue;
        public PropertiesUserControl()
        {
            InitializeComponent();
        }

        private void PropertiesFlowLayoutPanel_Paint(object sender, PaintEventArgs e)
        {

        }
        public void AddProperties(object Object)
        {
          
            Label TitleLabel=new Label();
            PropertiesUserControl propertiesusercontrol=new PropertiesUserControl();
            SelectedObject = Object;
            Type type = Object.GetType();
            PropertyInfo[] propertyinfoarray = type.GetProperties();
            TitleLabel.Text = type.Name+":"+Environment.NewLine;
     
             PropertiesFlowLayoutPanel.Controls.AddRange(new Control[]{TitleLabel,new Label()});
        
            foreach (PropertyInfo propertyinfo in propertyinfoarray)
            {
                ControlValueStructure controlvalue=new ControlValueStructure();
                controlvalue.ParentObject=Object;
                controlvalue.ParentInfo = propertyinfo;
                TitleLabel = new Label();
                TitleLabel.Text = propertyinfo.Name + ":";
                Label descriptionlabel = new Label();
                descriptionlabel.Text = propertyinfo.Name;
           
             
                switch (propertyinfo.PropertyType.Name)
                {
                    case "Boolean":
                        CheckBox checkbox = new CheckBox();
                        checkbox.Checked =(bool) propertyinfo.GetValue(Object, null);
                         PropertiesFlowLayoutPanel.Controls.Add(descriptionlabel);
                         PropertiesFlowLayoutPanel.Controls.Add(checkbox);
                         controlvalue.TargetObject = checkbox;
                        checkbox.Tag = controlvalue;
                        checkbox.CheckedChanged+=new EventHandler(ControlValue_Changed);
                        break;

                    case "String":
                      
                        TextBox value = new TextBox();
                        try
                        {
                            value.Text = propertyinfo.GetValue(Object, null).ToString();

                        }
                        catch (NullReferenceException)
                        {
                        }
                        catch (Exception)
	                    {
		                throw;
	                    }
             
                            PropertiesFlowLayoutPanel.Controls.Add(descriptionlabel);
                            PropertiesFlowLayoutPanel.Controls.Add(value);
                            controlvalue.TargetObject = value;
                            value.Tag = controlvalue;
                        value.TextChanged+=new EventHandler(ControlValue_Changed);

                        break;
                    case "Vector3":
                        Vector3 vec3 = (Vector3)propertyinfo.GetValue(Object, null); 
                        PropertiesFlowLayoutPanel.Controls.AddRange(new Control[]{TitleLabel,new Label()});
                        controlvalue.ParentInfo = propertyinfo;
                        SplitUpObject(vec3,controlvalue);
                        break;
                    case "Matrix":
                        Matrix matrix = (Matrix)propertyinfo.GetValue(Object, null);
                        PropertiesFlowLayoutPanel.Controls.AddRange(new Control[] { TitleLabel, new Label() });

                        SplitUpObject(matrix,controlvalue);
                        break;
                   
                    default:
                        
                        break;
                }
            }
        }

        private void SplitUpObject(object Object,ControlValueStructure controlvalue)
        {
        
            Type type = Object.GetType();
            FieldInfo[] fieldInfoArray = type.GetFields();
            foreach (FieldInfo fieldinfo in fieldInfoArray)
            {
                Label descriptionlabel = new Label();
                descriptionlabel.Text = fieldinfo.Name+":";
                TextBox value = new TextBox();
                try
                {
                    value.Text = fieldinfo.GetValue(Object).ToString();

                }
                catch (NullReferenceException)
                {
                }
                catch (Exception)
                {
                    throw;
                }
                PropertiesFlowLayoutPanel.Controls.AddRange(new Control[] { descriptionlabel, value });
                controlvalue.TargetInfo = fieldinfo;
                controlvalue.TargetObject = Object;
          
                controlvalue.ParentObject = SelectedObject;


                value.Tag = controlvalue;
                value.TextChanged += new EventHandler(ControlValue_Changed);
            }
        }

        private void PropertiesUserControl_Load(object sender, EventArgs e)
        {
           
        }
        private void ControlValue_Changed(object sender, EventArgs e)
        {
            Type controltype;
            PropertyInfo propertyinfo;
            PropertyInfo parentinfo;
           System.Reflection.FieldInfo fieldinfo;
           ControlValueStructure controlvalue=new ControlValueStructure();
            Control control = (Control)sender;

          
                try
                {
                    controlvalue = (ControlValueStructure)control.Tag;
                    fieldinfo = (FieldInfo)controlvalue.TargetInfo;
                    parentinfo = (PropertyInfo)controlvalue.ParentInfo;
                    object TargetObject = controlvalue.TargetObject;

                    if (fieldinfo != null)
                    {
                  controltype = fieldinfo.FieldType;
                        fieldinfo.SetValue(TargetObject, Convert.ChangeType(control.Text, controltype));
                     
                    }
                    controltype = parentinfo.PropertyType;

                    switch (controltype.Name)
                    {
                        case "Boolean":
                            CheckBox checkbox = (CheckBox)control;
                            parentinfo.SetValue(controlvalue.ParentObject, Convert.ChangeType(checkbox.Checked, controltype), null);
                            break;
                        case "String":
                            parentinfo.SetValue(controlvalue.ParentObject, Convert.ChangeType(control.Text, controltype), null);

                            break;
                        default:
                           parentinfo.SetValue(controlvalue.ParentObject, TargetObject, null);

                            break;
                    }

                }
                catch (FormatException)
                {
                }
                catch (Exception)
                {                   
                    throw;
                }
            }
        }
  
      
    }

